package com.polaris.live.utils.fragment

import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager

/**
 * fragment切换
 *
 * @author Created by lucas on 2023/10/17 20:38
 * @since 1.0.0
 */
class FragmentChangeManager(
    private val fragmentManager: FragmentManager,
    @param:IdRes
    private val viewId: Int,
    private val initFragments: List<Int>,
    private var mCurrentTab: Int = 0,
    private val creator: (Int) -> Fragment?
) {

    init {
        initFragments()
    }

    /**
     * 初始化fragments
     */
    private fun initFragments() {
        val fragments = fragmentManager.fragments
            .ifEmpty {
                initFragments.map {
                    getFragment(it, true)
                }
            }

        for (fragment in fragments) {
            hideFragment(fragment)
        }
        showFragment(getFragment(mCurrentTab))
    }

    /**
     * 界面切换控制
     */
    fun switchFragment(index: Int): Fragment? {
        hideFragment(getFragment(mCurrentTab))
        val fragment = getFragment(index)
        showFragment(fragment)
        mCurrentTab = index
        return fragment
    }

    /**
     * 清除全部Fragment
     */
    fun clearFragment() {
        for (fragment in fragmentManager.fragments) {
            fragmentManager.beginTransaction().remove(fragment).commitNow()
        }
    }

    /**
     * 获得当前fragment
     */
    fun getCurrentFragment(): Fragment? {
        return getFragment(mCurrentTab)
    }

    fun getCurrentFragment(position: Int): Fragment? {
        return fragmentManager.findFragmentByTag(position.toString())
    }

    private fun getFragment(position: Int, isInit: Boolean = false): Fragment? {
        val path = position.toString()
        var fragment = fragmentManager.findFragmentByTag(path)
        if (fragment == null) {
            fragment = creator(position)
            if (fragment == null) {
                return null
            }
            if (isInit) {
                fragmentManager.beginTransaction()
                    .add(viewId, fragment, path)
                    .commitNow()
            } else {
                fragmentManager.beginTransaction()
                    .add(viewId, fragment, path)
                    .commitAllowingStateLoss()
            }

        }
        return fragment
    }

    private fun showFragment(fragment: Fragment?) {
        if (fragment == null) {
            return
        }
        fragmentManager.beginTransaction()
            .show(fragment)
            .commitAllowingStateLoss()
    }

    fun hideFragment(fragment: Fragment?) {
        if (fragment == null) {
            return
        }
        fragmentManager.beginTransaction()
            .hide(fragment)
            .commitAllowingStateLoss()
    }
}